﻿using System;
using System.Collections.Generic;
using System.Text;
using Dogs.Controller;
using Dogs.Model;
using System.Windows.Forms;
using Animals.Model;

namespace Dogs
{
    public class DogsManager
    {

        AnimalFacade AnimalDB;
        Form1 form = null;
        FormAnimalInfo frmInfo = null;
        FormAnimalUpdate frmUpdate = null;

        SortedDictionary<long, string> Animals;
        Dictionary<int, long> IndexMappingMale;
        Dictionary<int, long> IndexMappingFemale;
        Dictionary<int, long> IndexSearch;
        Dictionary<int, long> TreeViewIndexMapping;


        public DogsManager(Form1 frm)
        {
            AnimalDB = new AnimalFacadeImpl();
            form = frm;
            IndexMappingMale = new Dictionary<int, long>();
            IndexMappingFemale = new Dictionary<int, long>();
            IndexSearch = new Dictionary<int, long>();
            TreeViewIndexMapping = new Dictionary<int, long>();
            Animals = AnimalDB.GetAllAnimals();
            frmInfo = new FormAnimalInfo();
            frmUpdate = new FormAnimalUpdate();
            frmUpdate.button1.Click += new EventHandler(this.UpdateAnimal);
        }


        public void RefreshAnimalsList()
        {
            Animals = new SortedDictionary<long, string>();
            Animals = AnimalDB.GetAllAnimals();            
        }

        public bool CheckNewAnimalDateBirth(DateTime BirthDate)
        {

            return AnimalDB.isEffectiveDate(BirthDate);

            return false;
        }

        public void AddAnimal(string Name, DateTime BirthDate, bool isMale, int formFatherId, int formMotherId)
        {
            long FatherID = -1;
            long MotehrID = -1;

            if (!(Name == null || Name.Trim().Equals("")))
            {
                if (formFatherId != -1)
                    FatherID = IndexMappingMale[formFatherId];
                if (formMotherId != -1)
                    MotehrID = IndexMappingFemale[formMotherId];

                AnimalDB.AddAnimal(Name, BirthDate, isMale, FatherID, MotehrID);
                ClearParentsLists();
                FillParentsList();
                Animals = AnimalDB.GetAllAnimals();
            }                            
        }

        //public void Get
        //{
        //    SortedDictionary<long, string> result = null;

        //    //result = AnimalDB.Ge
            
        //}
        public void RefreshTreeView(TreeNode node)
        {
            long animalID = -1;
            if (node != null)
            {
                animalID = (long)node.Tag;

                if (animalID != -1)
                {
                    form.TreeView1.Nodes.Clear();
                    TreeViewIndexMapping.Clear();

                    TreeNode roteNode = form.TreeView1.Nodes.Add(animalID.ToString(), animalID.ToString() + ", " + Animals[animalID]);
                    roteNode.Tag = animalID;
                    roteNode.Expand();                    

                    SetParents(animalID, roteNode, 0);
                    form.TreeView1.ExpandAll();
                    
                }
            }

        }

        public void BuildTree(long animalID)
        {            
            int treekey = -1;

            form.TreeView1.Nodes.Clear();

            if (animalID != -1) 
            {
                //animalID = IndexSearch[frmAnimalID];                            
                TreeNode roteNode = form.TreeView1.Nodes.Add(animalID.ToString(), animalID.ToString() + ", " + Animals[animalID]);
                roteNode.Tag = animalID;
                roteNode.Expand();
                //TreeViewIndexMapping.Add(treekey + 1, animalID);

                SetParents(animalID, roteNode, 0);
                form.TreeView1.ExpandAll();
            }

        }

        private void SetParents(long AnimalID, TreeNode root, int NodeLevel)
        {
            ParentsPair parents = null;
            TreeNode maleNode;
            TreeNode femaleNode;
            int treekey = -1;
            string fatherName = "";
            string motherName = "";

            if (NodeLevel == 4)
                return;

            if (GetTotalNodes(form.TreeView1) >= 16)
                return;

            parents = AnimalDB.GetParentsById(AnimalID);
            NodeLevel++;

            if ((parents != null) && (parents.FatherId != -1))
            {
                fatherName = parents.FatherId.ToString() + "," + Animals[parents.FatherId];
                if (NodeLevel == 1)
                    //fatherName = "----               " + fatherName;                
                    fatherName = "-----------------" + fatherName;                
                else
                    if (NodeLevel == 2)
                        //fatherName = "---------                                     " + fatherName;
                        fatherName = "-------------------------------                 " + fatherName;                    
                else
                        if (NodeLevel == 3 )
                            //fatherName = "-------- ---                                                          " + fatherName; 
                            fatherName = "-----------------------------------------------------                            " + fatherName; 
                else
                            if (NodeLevel  == 4)
                                //fatherName = "----------                                                                                       " + fatherName;        
                                fatherName = "------------------------------------------------------------------------------                                     " + fatherName; 
                            
                

                maleNode = root.Nodes.Add(parents.FatherId.ToString(), fatherName);
                maleNode.Tag = parents.FatherId;
                //treekey = GetTotalNodes(form.TreeView1);                
                //TreeViewIndexMapping.Add(treekey, parents.FatherId);                
                SetParents(parents.FatherId, maleNode, NodeLevel);
            }

            if ((parents != null) && (parents.MotherId != -1))
            {
                motherName = parents.MotherId.ToString() + ", " + Animals[parents.MotherId];
                if (NodeLevel == 1)
                    //motherName = "----               " + motherName;
                    motherName = "-----------------" + motherName;
                else
                    if (NodeLevel == 2)
                        //motherName = "-----                                  " + motherName;
                        motherName = "-------------------------------                 " + motherName;
                    else
                        if (NodeLevel == 3)
                            motherName = "-----------------------------------------------------                            " + motherName;
                        else
                            if (NodeLevel == 4)
                                motherName = "------------------------------------------------------------------------------                                     " + motherName; 
                //else   
                
                femaleNode = root.Nodes.Add(parents.MotherId.ToString(), motherName);
                femaleNode.Tag = parents.MotherId;
                //treekey = GetTotalNodes(form.TreeView1);                
                //TreeViewIndexMapping.Add(treekey, parents.FatherId);               
                SetParents(parents.MotherId, femaleNode, NodeLevel);
            }            
        }

        public void FillAnimalsbyDate(DateTime Date)
        {
            SortedDictionary<long, string> result = null;
            Dictionary<long, string> list = null;

            int key = -1;
            string value = "";
            list = new Dictionary<long, string>();

            //form.ListAnimals.Items.Clear();
            form.ListAnimals.DataSource = null;
            result = AnimalDB.GetAnimalsByDate(Date);
            //IndexSearch.Clear();
            if ((result != null) && (result.Count != 0))
            {
                foreach (KeyValuePair<long, string> item in result)
                {
                    list.Add(item.Key, item.Key.ToString() + ", " + item.Value);
                }
                form.ListAnimals.DataSource = new BindingSource(list, null);
                form.ListAnimals.DisplayMember = "Value";
                form.ListAnimals.ValueMember = "Key";
                //value = item.Key.ToString() + ", " + item.Value;
                //key = form.ListAnimals.Items.Add(value);
                //IndexSearch.Add(key, item.Key);
                
            }
            
        }

        public void FillAnimalsList()
        {
            string value = "";
            int key = -1;
            Dictionary<long, string> list = new Dictionary<long, string>();

            IndexSearch.Clear();
            //form.ListAnimals.Items.Clear();
            form.ListAnimals.DataSource = null;
            //foreach (KeyValuePair<long, string> item in Animals)
            //{               
            if (Animals.Count == 0)
                return;

            foreach (KeyValuePair<long, string> item in Animals)
            {
                list.Add(item.Key, item.Key.ToString() + ", " + item.Value);
            }
                form.ListAnimals.DataSource = new BindingSource(list, null);
                form.ListAnimals.DisplayMember = "Value";
                form.ListAnimals.ValueMember = "Key";
                //value = item.Key.ToString() + ", " + item.Value;
                //key = form.ListAnimals.Items.Add(value);
                //IndexSearch.Add(key, item.Key);
            //}

        }

        public void FillParentsList()
        {
            int key = -1;
            SortedDictionary<long, string> MaleAnimals;
            SortedDictionary<long, string> FemaleAnimals;

            MaleAnimals = AnimalDB.GetAllMaleAnimals();
            FemaleAnimals = AnimalDB.GetAllFemaleAnimals();

            if ((MaleAnimals != null) && (MaleAnimals.Count != 0))
            {
                foreach (KeyValuePair<long, string> item in MaleAnimals)
                {
                    key = form.ComboBoxMale.Items.Add(item.Key.ToString() + "," + item.Value);
                    IndexMappingMale.Add(key, item.Key);
                }
            }

            if ((FemaleAnimals != null) && (FemaleAnimals.Count != 0))
            {
                foreach (KeyValuePair<long, string> item in FemaleAnimals)
                {
                    key = form.ComboBoxFemale.Items.Add(item.Key.ToString() + "," + item.Value);
                    IndexMappingFemale.Add(key, item.Key);
                }
            }


        }

        private void ClearParentsLists()
        {
            form.ComboBoxFemale.Items.Clear();
            form.ComboBoxMale.Items.Clear();
            form.ComboBoxFemale.Text = "";
            form.ComboBoxMale.Text = "";            
            IndexMappingMale.Clear();
            IndexMappingFemale.Clear();
        }

        public void ShowAnimalInfo(TreeNode node)
        {
            long animalID = -1;
            Animal animal = null;

            if (node != null)
            {
                animalID = (long)node.Tag;
                animal = AnimalDB.GetAnimalById(animalID);

                if (animal != null)
                {
                    frmInfo.labelName.Text = animal.Name;
                    frmInfo.labelDate.Text = DateUtil.GetYearMonthDay(animal.BirthDate);
                    if (animal.Gender)
                    {
                        frmInfo.labelMale.Text = "Maschio";
                    }
                    else
                        frmInfo.labelMale.Text = "Femina";

                    if (animal.Parents.FatherId != -1)
                    {
                        frmInfo.labelFather.Text = Animals[animal.Parents.FatherId];
                    }
                    else
                        frmInfo.labelFather.Text = "";
                    if (animal.Parents.MotherId != -1)
                    {
                        frmInfo.labelMother.Text = Animals[animal.Parents.MotherId];
                    }
                    else
                        frmInfo.labelMother.Text = "";

                    frmInfo.ShowDialog();
                }
            }


        }

        public void FillUpdateAnimalForm(TreeNode node)
        {
            long animalID = -1;
            Animal animal = null;
            SortedDictionary<long, string> maleAnimals = null;
            SortedDictionary<long, string> femaleAnimals = null;

            if (node != null)
            {
                animalID = (long)node.Tag;
                animal = AnimalDB.GetAnimalById(animalID);

                if (animal != null)
                {
                    frmUpdate = new FormAnimalUpdate();
                    frmUpdate.button1.Click += new EventHandler(this.UpdateAnimal);
                    //frmUpdate.comboBoxFather.DataSource = null;
                    //frmUpdate.comboBoxMother.DataSource = null;

                    frmUpdate.labelID.Text = animalID.ToString();
                    frmUpdate.textBoxname.Text = animal.Name;
                    frmUpdate.dateTimePicker1.Value = animal.BirthDate;
                    if (animal.Gender)
                    {
                        frmUpdate.radioButton1.Checked = true;
                    }
                    else
                        frmUpdate.radioButton2.Checked = true;

                    maleAnimals = AnimalDB.GetAllMaleAnimals();
                    if (maleAnimals.Count > 0)
                    {
                        frmUpdate.comboBoxFather.DataSource = new BindingSource(maleAnimals, null);
                        frmUpdate.comboBoxFather.DisplayMember = "Value";
                        frmUpdate.comboBoxFather.ValueMember = "Key";
                        frmUpdate.comboBoxFather.SelectedItem = null;
                    }
                    if (animal.Parents.FatherId != -1)
                    {
                        frmUpdate.comboBoxFather.SelectedValue = animal.Parents.FatherId;
                        frmUpdate.checkBox1.Checked = true;
                    }

                    femaleAnimals = AnimalDB.GetAllFemaleAnimals();
                    if (femaleAnimals.Count > 0)
                    {
                        frmUpdate.comboBoxMother.DataSource = new BindingSource(femaleAnimals, null);
                        frmUpdate.comboBoxMother.DisplayMember = "Value";
                        frmUpdate.comboBoxMother.ValueMember = "Key";
                        frmUpdate.comboBoxMother.SelectedItem = null;
                    }
                    if (animal.Parents.MotherId != -1)
                    {
                        frmUpdate.comboBoxMother.SelectedValue = animal.Parents.MotherId;
                        frmUpdate.checkBox2.Checked = true;
                    }
                    else
                        frmInfo.labelMother.Text = "";

                    frmUpdate.ShowDialog();
                }
            }

        }

        public void UpdateAnimal(object sender, EventArgs e)
        {
            long animalID = -1;
            Animal animal = new Animal();
            string animalName = "";            

            if (frmUpdate.textBoxname.Text != "")
            {
                if (long.TryParse(frmUpdate.labelID.Text,out animalID))
                {                                                                                
                    animal.Name = frmUpdate.textBoxname.Text;                                        
                    animal.BirthDate = frmUpdate.dateTimePicker1.Value;
                    animal.Id = animalID;

                    if (frmUpdate.radioButton1.Checked)
                    {
                        animal.Gender = true;
                    }
                    else
                        animal.Gender = false;


                    animal.Parents = new ParentsPair();

                    if ((frmUpdate.checkBox1.Checked) && (frmUpdate.comboBoxFather.SelectedValue != null))
                    {
                        animal.Parents.FatherId = (long)frmUpdate.comboBoxFather.SelectedValue;
                    }
                    else
                        animal.Parents.FatherId = -1;

                    if ((frmUpdate.checkBox2.Checked) && (frmUpdate.comboBoxMother.SelectedValue != null))
                    {
                        animal.Parents.MotherId = (long)frmUpdate.comboBoxMother.SelectedValue;
                    }
                    else
                        animal.Parents.MotherId = -1;

                    AnimalDB.UpdateAnimal(animal);
                
                }
            }
            else
                MessageBox.Show("Animal Name empty!");
            frmUpdate.Close();
            frmUpdate.Dispose();
            RefreshAnimalsList();
            FillAnimalsList();
            BuildTree(animalID);
        }


        private int GetTotalNodes(TreeView treeView)
        {
            return this.GetTotalNodes(treeView.Nodes);
        }

        private int GetTotalNodes(TreeNodeCollection nodes)
        {
            int rootNodes = nodes.Count;

            foreach (TreeNode node in nodes)
            {
                rootNodes += this.GetTotalNodes(node.Nodes);
            }

            return rootNodes;
        }
    }
}
